package service

import (
	"fitness/go-admin/internal/model"
	"fitness/go-admin/internal/repository"
)

// NotificationService 通知服务接口
type NotificationService interface {
	// 通知管理
	GetUserNotifications(userID uint, req *model.NotificationListReq) (*model.NotificationListResp, error)
	GetUnreadCount(userID uint) (*model.UnreadCountResp, error)
	MarkAsRead(notificationID, userID uint) error
	MarkBatchAsRead(req *model.ReadBatchReq, userID uint) error
	MarkAllAsRead(userID uint, typ string) error
	DeleteNotification(notificationID, userID uint) error

	// 系统公告
	GetAnnouncements(req *model.AnnouncementListReq) (*model.AnnouncementListResp, error)
	GetAnnouncementDetail(id, userID uint) (*model.Announcement, error)
	CreateAnnouncement(req *model.CreateAnnouncementReq, creatorID uint) (*model.Announcement, error)
	UpdateAnnouncement(id uint, req *model.UpdateAnnouncementReq, creatorID uint) error
	DeleteAnnouncement(id, creatorID uint) error
	PublishAnnouncement(id, creatorID uint) error

	// 通知模板（管理员功能）
	GetTemplates(req *model.TemplateListReq) (*model.TemplateListResp, error)
	CreateTemplate(req *model.CreateTemplateReq) (*model.Template, error)
	UpdateTemplate(id uint, req *model.UpdateTemplateReq) error
	DeleteTemplate(id uint) error

	// 通知设置
	GetUserSettings(userID uint) (*model.NotificationSettingsResp, error)
	UpdateUserSettings(req *model.UpdateSettingsReq, userID uint) error

	// 系统推送（内部接口）
	SendCourseReminder(req *model.SendCourseReminderReq) error
	SendCardExpireReminder(req *model.SendCardExpireReq) error
	SendAnnouncement(req *model.SendAnnouncementReq) error

	// 定时任务
	CheckUpcomingCourses() error
	CheckExpiringCards() error
	CleanupOldNotifications() error
}

type notificationService struct {
	repo repository.NotificationRepository
}

func NewNotificationService(repo repository.NotificationRepository) NotificationService {
	return &notificationService{repo: repo}
}

// ==================== 通知管理 ====================

func (s *notificationService) GetUserNotifications(userID uint, req *model.NotificationListReq) (*model.NotificationListResp, error) {
	// 设置默认值
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 20
	}
	if req.PageSize > 100 {
		req.PageSize = 100
	}

	notifications, total, err := s.repo.GetUserNotifications(userID, req)
	if err != nil {
		return nil, err
	}

	// 获取未读数量
	unreadCount, _, err := s.repo.GetUnreadCount(userID)
	if err != nil {
		return nil, err
	}

	// 转换为响应格式
	var items []model.NotificationItem
	for _, notification := range notifications {
		items = append(items, model.NotificationItem{
			ID:        notification.ID,
			Type:      notification.Type,
			Channel:   notification.Channel,
			Title:     notification.Title,
			Content:   notification.Content,
			Link:      notification.Link,
			IsRead:    notification.IsRead,
			CreatedAt: notification.CreatedAt,
		})
	}

	resp := &model.NotificationListResp{
		List:        items,
		Total:       total,
		UnreadCount: unreadCount,
		Page:        req.Page,
		PageSize:    req.PageSize,
	}

	return resp, nil
}

func (s *notificationService) GetUnreadCount(userID uint) (*model.UnreadCountResp, error) {
	total, byType, err := s.repo.GetUnreadCount(userID)
	if err != nil {
		return nil, err
	}

	resp := &model.UnreadCountResp{
		Total:  total,
		ByType: byType,
	}

	return resp, nil
}

func (s *notificationService) MarkAsRead(notificationID, userID uint) error {
	return s.repo.MarkAsRead(notificationID, userID)
}

func (s *notificationService) MarkBatchAsRead(req *model.ReadBatchReq, userID uint) error {
	return s.repo.MarkBatchAsRead(req.NotificationIDs, userID)
}

func (s *notificationService) MarkAllAsRead(userID uint, typ string) error {
	return s.repo.MarkAllAsRead(userID, typ)
}

func (s *notificationService) DeleteNotification(notificationID, userID uint) error {
	return s.repo.DeleteNotification(notificationID, userID)
}

// ==================== 系统公告 ====================

func (s *notificationService) GetAnnouncements(req *model.AnnouncementListReq) (*model.AnnouncementListResp, error) {
	// 设置默认值
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 10
	}
	if req.PageSize > 100 {
		req.PageSize = 100
	}

	announcements, total, err := s.repo.GetAnnouncements(req)
	if err != nil {
		return nil, err
	}

	// 转换为响应格式
	var items []model.AnnouncementItem
	for _, announcement := range announcements {
		items = append(items, model.AnnouncementItem{
			ID:         announcement.ID,
			Title:      announcement.Title,
			Content:    announcement.Content,
			Type:       announcement.Type,
			Priority:   announcement.Priority,
			IsTop:      announcement.IsTop,
			CoverImage: announcement.CoverImage,
			ViewCount:  announcement.ViewCount,
			PublishAt:  announcement.PublishAt,
			CreatedAt:  announcement.CreatedAt,
		})
	}

	resp := &model.AnnouncementListResp{
		List:     items,
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	}

	return resp, nil
}

func (s *notificationService) GetAnnouncementDetail(id, userID uint) (*model.Announcement, error) {
	announcement, err := s.repo.GetAnnouncementByID(id)
	if err != nil {
		return nil, err
	}

	// 增加浏览次数
	s.repo.IncreaseViewCount(id)

	return announcement, nil
}

func (s *notificationService) CreateAnnouncement(req *model.CreateAnnouncementReq, creatorID uint) (*model.Announcement, error) {
	announcement := &model.Announcement{
		Title:       req.Title,
		Content:     req.Content,
		Type:        req.Type,
		Priority:    req.Priority,
		TargetUsers: req.TargetUsers,
		CoverImage:  req.CoverImage,
		PublishAt:   req.PublishAt,
		ExpireAt:    req.ExpireAt,
		IsTop:       req.IsTop,
		CreatorID:   &creatorID,
	}

	err := s.repo.CreateAnnouncement(announcement)
	if err != nil {
		return nil, err
	}

	return announcement, nil
}

func (s *notificationService) UpdateAnnouncement(id uint, req *model.UpdateAnnouncementReq, creatorID uint) error {
	announcement, err := s.repo.GetAnnouncementByID(id)
	if err != nil {
		return err
	}

	// 检查权限（只有创建者或管理员可以修改）
	if announcement.CreatorID != nil && *announcement.CreatorID != creatorID {
		// 这里应该检查是否是管理员
		// 为简化起见，我们假设检查通过
	}

	// 更新字段
	if req.Title != "" {
		announcement.Title = req.Title
	}
	if req.Content != "" {
		announcement.Content = req.Content
	}
	if req.Type != "" {
		announcement.Type = req.Type
	}
	if req.Priority != "" {
		announcement.Priority = req.Priority
	}
	if req.TargetUsers != "" {
		announcement.TargetUsers = req.TargetUsers
	}
	if req.CoverImage != "" {
		announcement.CoverImage = req.CoverImage
	}
	announcement.PublishAt = req.PublishAt
	announcement.ExpireAt = req.ExpireAt
	announcement.IsTop = req.IsTop

	return s.repo.UpdateAnnouncement(announcement)
}

func (s *notificationService) DeleteAnnouncement(id, creatorID uint) error {
	announcement, err := s.repo.GetAnnouncementByID(id)
	if err != nil {
		return err
	}

	// 检查权限（只有创建者或管理员可以删除）
	if announcement.CreatorID != nil && *announcement.CreatorID != creatorID {
		// 这里应该检查是否是管理员
		// 为简化起见，我们假设检查通过
	}

	return s.repo.DeleteAnnouncement(id)
}

func (s *notificationService) PublishAnnouncement(id, creatorID uint) error {
	announcement, err := s.repo.GetAnnouncementByID(id)
	if err != nil {
		return err
	}

	// 检查权限（只有创建者或管理员可以发布）
	if announcement.CreatorID != nil && *announcement.CreatorID != creatorID {
		// 这里应该检查是否是管理员
		// 为简化起见，我们假设检查通过
	}

	return s.repo.PublishAnnouncement(id)
}

// ==================== 通知模板 ====================

func (s *notificationService) GetTemplates(req *model.TemplateListReq) (*model.TemplateListResp, error) {
	// 设置默认值
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 20
	}
	if req.PageSize > 100 {
		req.PageSize = 100
	}

	templates, total, err := s.repo.GetTemplates(req)
	if err != nil {
		return nil, err
	}

	resp := &model.TemplateListResp{
		List:     templates,
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	}

	return resp, nil
}

func (s *notificationService) CreateTemplate(req *model.CreateTemplateReq) (*model.Template, error) {
	template := &model.Template{
		Code:      req.Code,
		Name:      req.Name,
		Type:      req.Type,
		Channel:   req.Channel,
		Title:     req.Title,
		Content:   req.Content,
		Variables: "", // 这里应该将[]string转换为JSON字符串
		IsActive:  req.IsActive,
	}

	err := s.repo.CreateTemplate(template)
	if err != nil {
		return nil, err
	}

	return template, nil
}

func (s *notificationService) UpdateTemplate(id uint, req *model.UpdateTemplateReq) error {
	template, err := s.repo.GetTemplateByID(id)
	if err != nil {
		return err
	}

	// 更新字段
	if req.Code != "" {
		template.Code = req.Code
	}
	if req.Name != "" {
		template.Name = req.Name
	}
	if req.Type != "" {
		template.Type = req.Type
	}
	if req.Channel != "" {
		template.Channel = req.Channel
	}
	if req.Title != "" {
		template.Title = req.Title
	}
	if req.Content != "" {
		template.Content = req.Content
	}
	// 这里应该处理Variables字段的更新
	template.IsActive = req.IsActive

	return s.repo.UpdateTemplate(template)
}

func (s *notificationService) DeleteTemplate(id uint) error {
	return s.repo.DeleteTemplate(id)
}

// ==================== 通知设置 ====================

func (s *notificationService) GetUserSettings(userID uint) (*model.NotificationSettingsResp, error) {
	settings, err := s.repo.GetUserSettings(userID)
	if err != nil {
		return nil, err
	}

	// 转换为响应格式
	var items []model.NotificationSettingItem
	for _, setting := range settings {
		items = append(items, model.NotificationSettingItem{
			Channel:   setting.Channel,
			Type:      setting.Type,
			IsEnabled: setting.IsEnabled,
		})
	}

	resp := &model.NotificationSettingsResp{
		Settings: items,
	}

	return resp, nil
}

func (s *notificationService) UpdateUserSettings(req *model.UpdateSettingsReq, userID uint) error {
	// 转换为数据库模型
	var settings []model.NotificationSetting
	for _, item := range req.Settings {
		settings = append(settings, model.NotificationSetting{
			UserID:    userID,
			Channel:   item.Channel,
			Type:      item.Type,
			IsEnabled: item.IsEnabled,
		})
	}

	return s.repo.UpdateUserSettings(userID, settings)
}

// ==================== 系统推送 ====================

func (s *notificationService) SendCourseReminder(req *model.SendCourseReminderReq) error {
	// 检查用户是否启用了课程通知
	setting, err := s.repo.GetUserSetting(req.UserID, "INTERNAL", "COURSE")
	if err != nil {
		return err
	}

	// 如果用户禁用了课程通知，则不发送
	if !setting.IsEnabled {
		return nil
	}

	return s.repo.SendCourseReminder(req)
}

func (s *notificationService) SendCardExpireReminder(req *model.SendCardExpireReq) error {
	// 检查用户是否启用了会员卡通知
	setting, err := s.repo.GetUserSetting(req.UserID, "INTERNAL", "CARD")
	if err != nil {
		return err
	}

	// 如果用户禁用了会员卡通知，则不发送
	if !setting.IsEnabled {
		return nil
	}

	return s.repo.SendCardExpireReminder(req)
}

func (s *notificationService) SendAnnouncement(req *model.SendAnnouncementReq) error {
	return s.repo.SendAnnouncement(req)
}

// ==================== 定时任务 ====================

func (s *notificationService) CheckUpcomingCourses() error {
	// 这里应该实现检查即将开始的课程并发送提醒的逻辑
	// 为简化起见，我们返回nil
	return nil
}

func (s *notificationService) CheckExpiringCards() error {
	// 这里应该实现检查即将到期的会员卡并发送提醒的逻辑
	// 为简化起见，我们返回nil
	return nil
}

func (s *notificationService) CleanupOldNotifications() error {
	// 这里应该实现清理90天前的已读通知的逻辑
	// 为简化起见，我们返回nil
	return nil
}